home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_10_11 / 1011125a < prev    next >
Text File  |  1992-09-07  |  20KB  |  424 lines

  1.  
  2. echo Extracting splot.c...
  3. cat <<WRAP_EOF >splot.c
  4. /**************************************************************************
  5.  *  SPLOT - Builds a screen plot of data points and curves.
  6.  *       Creates HP LaserJet .PCL and PostScript .PS files for printing.
  7.  *
  8.  *   *pstfil & *hpfil - output files (may be NULL if not needed)
  9.  *      xdivs & ydivs - number of X and Y axis divisions
  10.  *      xgrid & ygrid - grid line flags (1 for lines, 0 for no lines)
  11.  *             nplots - number of curves (each has 0 or more symbol points)
  12.  *        *x[] & *y[] - Arrays of pointers to arrays of X and Y  values
  13.  *        npts_pnts[] - array of number of symbol points for each curve
  14.  *         npts_tot[] - array of number of total  points for each curve
  15.  *              title - character array for graph title
  16.  *        xaxis,yaxis - character arrays for X and Y axis labels
  17.  *             *msg[] - pointers to strings to appear in a message box
  18.  *             nmsg[] - number of strings in message box (0 for no box) and
  19.  *                      X and Y coordinates of beginning of first string
  20.  *                      (640 x 480 screen cordinates)
  21.  *
  22.  *  For "curve" i of the nplots "curves" the first npts_pnts[i] points are
  23.  *  plotted with symbols only. The remaining points up to npts_tot[i-1] are
  24.  *  plotted with connecting lines but no symbols. The number of either
  25.  *  symbols or connecting lines, but not both, may be 0.
  26. **************************************************************************/
  27. #include <stdio.h>
  28. #include <math.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <conio.h>
  32. #include <dos.h>
  33. #include <stdarg.h>
  34. #include <graphics.h>
  35. #include aalloc.h>
  36. #define  CORE   0         /* = 1 for coreleft() report after initgraph()   */
  37. #define   YTEXT YD+19.          /* Y cordinate for xaxis labeling          */
  38. /*   XL=X axis start, XR=X axis end,  YU=Y axis upper, YD=Y axis lower.    */
  39. double XL=72. ,XR=619. ,YU=29. ,YD=441. ,YDM=479.;
  40. FILE   *postfile;               /* File scope PostScript output file       */
  41. int    DIRECTION;               /* 0 for horizontal text, 1 for vertical   */
  42. int    YAXOFF;                  /* Offset for Y axis title                 */
  43. int    GraphDriver;             /* The Graphics device driver              */
  44. int    GraphMode;               /* The Graphics mode value                 */
  45. int    ErrorCode;               /* Reports any graphics errors             */
  46.  
  47. /*      Function prototypes */
  48. void linscale (double xmin,double xmax,int n,double *xminp,double *xmaxp,
  49.          doulle *dist);
  50. void outlin(double x1, double y1, double x2, double y2);
  51. void box(double x1,double y1,double x2,double y2);
  52. void linaxis(int axis,double start,double dist,int divs, int grids, double dotsperdiv,
  53.          int ticksize);
  54. void changetextstyle(int direction, int charsize);
  55. void formx(char* str,double x, int *prec, int *typ, int kon);
  56. void outtxt(double x, double y, int horiz, int vert, char *txt);
  57. void symbol(double x,double y, int num);
  58. void msgbox(char *msg[], int *nmsg);
  59. void hpltit(FILE *hpfile);
  60.  
  61. void splot(FILE *pstfil, FILE *hpfile, int xdivs, int ydivs, int xgrid,
  62.       int ygrid, int nplots, double *x[], double *y[], int *npts_pnts,
  63.       int *npts_tot, char *title, char *xaxis, char *yaxis,char *msg[], int *nmsg)
  64. { double xdotsprdiv, ydotsprdiv,xstart, xstop, ystart, ystop,xdata, ydata,
  65.            xdist, ydist, xlast, ylast, xscale, yscale, limits[4];
  66.   unsigned long core;
  67.   int    i, j, ticksize;
  68. #if  CORE==1
  69.   char   nar[90];
  70. #endif
  71.  
  72.   core=(unsigned long)coreleft();
  73.   if (core<16000L)
  74.   { fprintf(stderr,"Only %lu core left at entry to PLOTS. About 16000 needed.\n",core);
  75.     fprintf(stderr,"^C to stop and use COMPACT or LARGE model, any other key to procede\n");
  76.     i=getch(); if (i==3) exit(1);
  77.   }
  78.   postfile=pstfil;  ticksize = 5;  YAXOFF=0;
  79.   fprintf(postfile,"%%!PS-Adobe-2.0 EPSF-1.2\n%%%%BoundingBox: 0 0 612 792\n");
  80.   fprintf(postfile,"/cntrj{dup stringwidth pop 2 div neg 0 rmoveto} bind def\n");
  81.   fprintf(postfile,"/rtj{dup stringwidth pop neg 0 rmoveto} bind def\n");
  82.   fprintf(postfile,"552 80 translate 90 rotate \n");
  83.   /* Calculate dotsperdiv and adjust YU and XR to an integral multiple */
  84.   xdotsprdiv = (int)((XR - XL) / xdivs);  ydotsprdiv = (int)((YD - YU) / ydivs);
  85.   XR=XL+(int)(xdivs*xdotsprdiv);  YU=YD-(int)(ydivs*ydotsprdiv);
  86.   /* Determine the upper and lower limits of the data. */
  87.   limits[0] = limits[2] =  9.99e+99;   limits[1] = limits[3] = -9.99e+99;
  88.   for (i=0; i<nplots; ++i)  for (j=0; j<npts_tot[i]; ++j)
  89.   { if (x[i][j]<limits[0]) limits[0]=x[i][j]; if (x[i][j]>limits[1]) limits[1]=x[i][j];
  90.     if (y[i][j]<limits[2]) limits[2]=y[i][j]; if (y[i][j]>limits[3]) limits[3]=y[i][j];
  91.   }
  92.   /* initialize graphics (hi-res), draw and label graph */
  93.   GraphDriver=(int)DETECT;               /* Request auto-detection       */
  94.   initgraph (&GraphDriver, &GraphMode,"");
  95.   ErrorCode=graphresult();               /* Read result of initialization*/
  96.   if (ErrorCode!=(int)grOk)              /* Error occured during init    */
  97.   { fprintf(stderr,"Graphics System Error: %s\n",grapherrormsg(ErrorCode));
  98.     exit(1);
  99.   }
  100.   if (GraphDriver!= (int)VGA)
  101.   { fprintf(stderr,"The screen plot program requires a VGA monitor\n");
  102.     closegraph();   exit(1);
  103.   }
  104.   changetextstyle(0,5);  /* Text size and style for axis numbers */
  105. #if CORE==1
  106.   sprintf(nar,"After graphics initialization there is %lu core left",
  107.           (unsigned long)coreleft());
  108.   outtxt(0.,15.,0,0,nar);
  109.   outtxt(0.,30.,0,0,"At least 1000 is needed. Hit enter to procede."); getch();
  110. #endif
  111.   /* box(0.,0.,639.,479.); */   /* Optional bounding box for checking layout. */
  112.   box(XL, YU, XR, YD);     /* Draw bounding box */
  113.   /* do linear plot scaling */
  114.   linscale (limits[2],limits[3],ydivs,&ystart,&ystop,&ydist);
  115.   linscale (limits[0],limits[1],xdivs,&xstart,&xstop,&xdist);
  116.   /* draw and label axes */
  117.   linaxis (0,ystart,ydist,ydivs,ygrid,ydotsprdiv,ticksize);
  118.   linaxis (1,xstart,xdist,xdivs,xgrid,xdotsprdiv,ticksize);
  119.   changetextstyle(0,6);  outtxt(325.,12.,1,0,title);
  120.   changetextstyle(0,5);  outtxt((XL+XR)/2.,YDM-2.,1,0,xaxis);
  121.   changetextstyle(1,5);
  122.   outtxt(XL-10.-(double)YAXOFF,(YU+YD)/2.,2,1,yaxis);
  123.   changetextstyle(0,5);
  124.   xscale=xdotsprdiv/xdist;   yscale=ydotsprdiv/ydist;
  125.   /* Plot the data points */
  126.   for (i=0; i<nplots; ++i)  for (j=0; j<npts_pnts[i]; ++j)
  127.   { xdata=(int)(XL+(x[i][j]-xstart)*xscale); ydata=(int)(YD-(y[i][j]-ystart)*yscale);
  128.     symbol(xdata,ydata,i);
  129.   }
  130.   /* Plot the curves */
  131.   for (i=0; i<nplots; ++i) for (j=npts_pnts[i]; j<npts_tot[i]; ++j)
  132.   { xdata=XL+(x[i][j]-xstart)*xscale;  ydata=YD-(y[i][j]-ystart)*yscale;
  133.     if (j==npts_pnts[i]) { xlast=xdata; ylast=ydata; continue; }
  134.     outlin(xlast,ylast,xdata,ydata);  xlast=xdata;  ylast=ydata;
  135.   }
  136.   if (nmsg[0]) msgbox(msg,nmsg);
  137.   fprintf(postfile," showpage\n%c\n",4);
  138.   if (hpfile!=NULL) hpltit(hpfile);
  139.   (void)getch();   /* Hold the graph on screen till a key is pressed. */
  140.   closegraph();
  141.   (void)fclose(postfile);
  142.   (void)fclose(hpfile);
  143. } /********************* end function plots(........) **************/
  144. /*************************************************************************
  145.  * LINSCALE - Define linear scale limits - fixed interval.
  146.  *  Given estimated maximum and minimum values and a requested number of
  147.  *  intervals, adjust the extrema to encompass the same number of equal
  148.  *  intervals of size dist, such that they are "nice" values for a plot.
  149.  *
  150.  *  Input:   xmin - minimum value.
  151.  *           xmax - maximum value.
  152.  *              n - number of data intervals required.
  153.  *  Output: xminp - adjusted minimum value.
  154.  *          xmaxp - adjusted maximum value.
  155.  *           dist - data interval size.
  156.  *
  157.  *  xmin, xmax, and n are not modified.
  158.  *
  159.  *  vint(*) is an array of acceptable values for dist (times  an integer power of 10).
  160.  *
  161.  *  Adapted from C. R. Lewart, Comm. ACM,  algorithm 463 (1972).
  162.  ************************************************************************/
  163. void linscale (double xmin, double xmax, int n, double *xminp,
  164.       double *xmaxp, double *dist)
  165. { int     i, m1, m2, nal, np,  nx, nvnt;
  166.   double  a, b, fm1, fm2;
  167.   double del=2.0e-9, vint[]={1.,2.,4.,5.,6.,8